﻿using 名词表;
using 战斗系统原型.数据模型与词表;

namespace 战斗系统原型.战斗系统
{
    public class 战斗流程
    {
        public 数据组 数据组 { get; set; }
        public 战斗流程(数据组 数据组)
        {
            this.数据组 = 数据组;
        }
        #region 流程控制
        public void 启动新战斗(ref 战场属性 战场, List<角色> 敌方队伍列表, Dictionary<队伍类型, 队伍> 队伍数据)
        {
            战场 = new 战场属性();//建立新战场
            队伍数据[队伍类型.敌方队伍] = new 队伍();
            队伍数据[队伍类型.敌方队伍].队伍名称 = "敌方队伍";
            List<物品> 掉落物品清单 = new List<物品>();
            int 掉落金钱 = 0;
            int 击败经验值 = 0;
            foreach (var 敌人 in 敌方队伍列表)
            {
                队伍数据[队伍类型.敌方队伍].队伍成员.Add(敌人);
                击败经验值 += 敌人.掉落经验值;
                掉落金钱 += 敌人.掉落金钱;
                敌人.操作模式 = 角色.操作者.AI;
            }
            队伍数据[队伍类型.敌方队伍].物品列表 = 掉落物品清单;
            队伍数据[队伍类型.敌方队伍].队伍金钱 = 掉落金钱;
            队伍数据[队伍类型.敌方队伍].队伍经验值 = 击败经验值;
            实体数据.数据组.战场数据.启动战斗时间 = DateTime.Now;
            实体数据.数据组.战场数据.下一行动 = 下一行动;
            实体数据.数据组.战场数据.重新计算行动 = 刷新行动条;
            实体数据.数据组.战场数据.队伍数据 = 队伍数据;
            下一行动(战场, 队伍数据);
        }
        public void 注册角色战斗菜单()
        {
            选项组 战斗选项组 = new 选项组()
            {
                选项列表 = new List<选项>()
                 {
                     new 菜单_战斗(),
                     new 菜单_防御(),
                     new 菜单_物品(),
                     new 菜单_符卡与符术()
                 }
            };
            数据组.人物数据[主角团姓名.玩家定义值.ToString()].注册战斗选项 = new 选项组()
            {
                选项组名称 = 主角团姓名.玩家定义值.ToString(),
                选项列表 = 战斗选项组.选项列表
            };
            数据组.人物数据[主角团姓名.东风谷早苗.ToString()].注册战斗选项 = new 选项组()
            {
                选项组名称 = 主角团姓名.东风谷早苗.ToString(),
                选项列表 = 战斗选项组.选项列表
            };

        }
        public virtual void 触发AI行动(角色 使用角色)
        {
            if (系统与设置.程序运行 == false) { return; }
            AI模式 AI模式 = AI模式.随意攻击;
            if (AI模式 == AI模式.随意攻击)
            {
                AI战斗.随意攻击(使用角色, 数据组.战场数据, 队伍类型.我方队伍);
            }
            
        }
        public virtual void 触发玩家行动(角色 使用角色)
        {
            显示.日志输出(显示.日志类型.中断, "请重写玩家行动显示方法");
        }
        public virtual void UI战斗结束(战场属性 战场, 队伍类型 失败队伍, 队伍类型 胜利队伍)
        {
            显示.日志输出(显示.日志类型.中断, "请重写战斗结束显示方法");
        }
        public void 战斗结束(战场属性 战场, 队伍类型 失败队伍, 队伍类型 胜利队伍)
        {
            战场.队伍数据![胜利队伍].物品列表.AddRange(战场.队伍数据[失败队伍].物品列表);
            战场.队伍数据[胜利队伍].队伍金钱 += 战场.队伍数据[失败队伍].队伍金钱;
            战场.队伍数据[胜利队伍].队伍经验值 += 战场.队伍数据[失败队伍].队伍经验值;
            UI战斗结束(战场, 失败队伍, 胜利队伍);
        }

        public bool 战斗结束判定(战场属性 战场, Dictionary<队伍类型, 队伍> 队伍数据, bool 执行默认结束动作 = true)
        {
            foreach (var 队伍 in 队伍数据)
            {
                var 剩余队员 = 队伍.Value.队伍成员.FindAll(x => x.角色状态 == 角色.状态.正常);
                if (剩余队员.Count == 0)
                {
                    if (执行默认结束动作)
                    {
                        战斗默认结束动作(队伍, 战场);
                        return true;
                    }
                }
            }
            return false;
        }

        public void 战斗默认结束动作(KeyValuePair<队伍类型, 队伍> 队伍, 战场属性 战场)
        {
            if (队伍.Key == 队伍类型.我方队伍) { 战斗结束(战场, 队伍类型.我方队伍, 队伍类型.敌方队伍); }
            if (队伍.Key == 队伍类型.敌方队伍) { 战斗结束(战场, 队伍类型.敌方队伍, 队伍类型.我方队伍); }

        }
        #endregion

        #region 行动条
        public void 填充行动条(战场属性 战场, Dictionary<队伍类型, 队伍> 队伍数据)
        {
            //判断战场行动条是否已经填满了三次行动
            if (战场.行动条.Count < 3)
            {
                //如果没有填满就递归把数据填满
                var 行动顺序 = 计算行动顺序(队伍数据);
                战场.行动条.Add(行动顺序);
                刷新行动条(战场, 队伍数据);
                return;
            }
        }
        public void 刷新行动条(战场属性 战场, Dictionary<队伍类型, 队伍> 队伍数据)
        {
            填充行动条(战场, 队伍数据);
            //判断战场行动条中已经死亡的角色并执行排除操作
            foreach (var 行动条 in 战场.行动条)
            {
                转换.战场数据计算.删除死亡与消失角色(行动条);
            }
            //判断战斗是否已经结束
            战斗结束判定(战场, 队伍数据);
        }
        public void 下一行动(战场属性 战场, Dictionary<队伍类型, 队伍> 队伍数据)
        {
            void 初次行动()
            {
                刷新行动条(战场, 队伍数据);
                var 当前行动角色 = 战场.行动条[0].ElementAt(0);
                战场.当前行动角色 = 当前行动角色;
                if (当前行动角色.操作模式 == 角色.操作者.玩家)
                {
                    触发玩家行动(战场.行动条[0].ElementAt(0));
                }
                if (当前行动角色.操作模式 == 角色.操作者.AI)
                {
                    触发AI行动(战场.行动条[0].ElementAt(0));
                }
            }
            void 再次行动()
            {
                战场.行动条[0].RemoveAt(0);
                if (战场.行动条[0].Count == 0)
                {
                    战场.行动条.RemoveAt(0);

                    刷新行动条(战场, 队伍数据);
                    战场.回合数++;
                    战场.日志.Add($"----- 进入第{战场.回合数}回合 -----");
                }
                var 当前行动角色 = 战场.行动条[0].ElementAt(0);
                战场.当前行动角色 = 当前行动角色;
                if (当前行动角色.操作模式 == 角色.操作者.玩家)
                {
                    触发玩家行动(战场.行动条[0].ElementAt(0));
                }
                if (当前行动角色.操作模式 == 角色.操作者.AI)
                {
                    触发AI行动(战场.行动条[0].ElementAt(0));
                }
            }
            if (战场.行动条.Count == 0) { 初次行动(); }
            else { 再次行动(); }
        }

        private List<角色> 计算行动顺序(Dictionary<队伍类型, 队伍> 队伍数据)
        {
            var 战场所有角色 = new List<角色>();
            战场所有角色.AddRange(队伍数据[队伍类型.我方队伍].队伍成员);
            战场所有角色.AddRange(队伍数据[队伍类型.敌方队伍].队伍成员);
            战场所有角色.Sort((a, b) => (b.速度 + b.速度附加).CompareTo((a.速度 + a.速度附加)));
            return 战场所有角色;
        }

        #endregion
    }
}
